package org.codesamples.hibernate.flush;

import static junit.framework.Assert.*;

import org.codesamples.hibernate.base.HibernateUtil;
import org.codesamples.hibernate.model.onetoone.Father;
import org.hibernate.Session;
import org.junit.Assert;

public class HibernateWithoutTransaction {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		HibernateWithoutTransaction hibernateWithoutTransaction = new HibernateWithoutTransaction();
		
		System.out.println("================= present In Session And Database =================");
		hibernateWithoutTransaction.presentInSessionAndDatabase();
		
		System.out.println("================= present In Session And Not In Database Without Flush =================");
		hibernateWithoutTransaction.presentInSessionAndNotInDatabaseWithoutFlush();
		
		System.out.println("================= present In Session And Not In Database With Flush =================");
		hibernateWithoutTransaction.presentInSessionAndNotInDatabaseWithFlush();
		
		System.out.println("================= present In Session And Not In Database With Flush And Clear =================");
		hibernateWithoutTransaction.presentInSessionAndNotInDatabaseWithFlushAndClear();
		
	}
	
	public void presentInSessionAndDatabase() {		
		Session session = HibernateUtil.getSession();

		Father father = new Father();
		father.setName("jeorge 1");
		session.save(father);
		
		/* check data in session */
		Father fatherInSession = (Father) session.get(Father.class, 1);
		assertEquals(fatherInSession.getId(), 1);
		assertEquals(fatherInSession.getName(), "jeorge 1");
		
		/* check data in database */		
		String dbFatherName = HibernateUtil.getData("select name from Father Where Id = 1");
		System.out.println(dbFatherName);
		Assert.assertTrue(fatherInSession.getName().equals(dbFatherName));
	}
	
	public void presentInSessionAndNotInDatabaseWithoutFlush() {
		Session session = HibernateUtil.getSession();

		Father father = new Father();
		father.setName("jeorge 2");
		session.save(father);
		
		/* change the name of father entity (applicable only in session will not be updated in database until flush/update) */
		father.setName("jeorge 2 changed");
				
		/* check data in session */
		Father fatherInSession = (Father) session.get(Father.class, 2);		
		assertEquals(fatherInSession.getId(), 2);
		assertEquals(fatherInSession.getName(), "jeorge 2 changed");
		
		/* check data in database */		
		String dbFatherName = HibernateUtil.getData("select name from Father Where Id = 2");
		System.out.println("fatherInSession :: " + fatherInSession.getName());
		System.out.println("dbFatherName :: " + dbFatherName);
		Assert.assertFalse(fatherInSession.getName().equals(dbFatherName));
	}
	
	public void presentInSessionAndNotInDatabaseWithFlush() {
		Session session = HibernateUtil.getSession();

		Father father = new Father();
		father.setName("jeorge 3");
		session.save(father);
		
		/* change the name of father entity (applicable only in session will not be updated in database until flush/update) */
		father.setName("jeorge 3 changed");
				
		session.flush();
		
		//father.setName("jeorge 2 changed again");		
		//session.clear();
		
		/* check data in session */
		Father fatherInSession = (Father) session.get(Father.class, 3);		
		assertEquals(fatherInSession.getId(), 3);
		assertEquals(fatherInSession.getName(), "jeorge 3 changed");
		
		/* check data in database */		
		String dbFatherName = HibernateUtil.getData("select name from Father Where Id = 3");
		System.out.println("fatherInSession :: " + fatherInSession.getName());
		System.out.println("dbFatherName :: " + dbFatherName);
		Assert.assertTrue(fatherInSession.getName().equals(dbFatherName));
	}
	
	public void presentInSessionAndNotInDatabaseWithFlushAndClear() {
		Session session = HibernateUtil.getSession();

		Father father = new Father();
		father.setName("jeorge 4");
		session.save(father);

		/* change the name of father entity (applicable only in session will not be updated in database until flush/update) */
		father.setName("jeorge 4 changed");

		session.flush();
		
		father.setName("jeorge 4 changed again");
		
		session.clear();
		
		/* check data in session */
		Father fatherInSession = (Father) session.get(Father.class, 4);		
		assertEquals(fatherInSession.getId(), 4);
		assertEquals(fatherInSession.getName(), "jeorge 4 changed");
		
		/* check data in database */		
		String dbFatherName = HibernateUtil.getData("select name from Father Where Id = 4");
		System.out.println("fatherInSession :: " + fatherInSession.getName());
		System.out.println("dbFatherName :: " + dbFatherName);
		Assert.assertTrue(fatherInSession.getName().equals(dbFatherName));
	}
}
